package com.e1xp.deport_management_system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.e1xp.deport_management_system.entity.Product;
import com.e1xp.deport_management_system.entity.ProductRack;
import com.e1xp.deport_management_system.exception.CustomException;
import com.e1xp.deport_management_system.exception.CustomExceptionType;
import com.e1xp.deport_management_system.mapper.ProductMapper;
import com.e1xp.deport_management_system.mapper.ProductRackMapper;
import com.e1xp.deport_management_system.service.IProductService;
import com.e1xp.deport_management_system.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author E1xP
 * @since 2021-04-09
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    @Resource
    ProductRackMapper productRackMapper;

    @Resource
    ProductMapper productMapper;

    @Resource
    IUserService userService;

    /**
     * 获取商品总数
     *
     * @return 商品总数
     */
    @Override
    public long getCount(long instanceId) {
        return productMapper.getSumProduct(instanceId);
    }

    /**
     * 用于添加产品
     * @param product 产品实体
     * @throws CustomException 当实例不存在，产品id已存在时，抛出该异常
     */
    @Override
    public void add(Product product) throws CustomException {
        if (!userService.isInstance(product.getInstanceId())) {
            //若不存在该实例
            throw new CustomException(CustomExceptionType.INSTANCE_NOT_FOUND_ERROR, "该实例不存在");
        }
        if (this.isProduct(product.getId())) {
            //若商品已存在
            throw new CustomException(CustomExceptionType.PRODUCT_HAD_BEEN_ADD, "已存在同产品号产品");
        }
        productMapper.insert(product);
    }

    /**
     * 获取实例的所有商品列表
     *
     * @param instanceId 实例id
     * @return 商品列表
     */
    @Override
    public List<Product> getList(long instanceId) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("instance_id", instanceId);
        return productMapper.selectList(queryWrapper);
    }

    /**
     * 用产品id列表查询对应产品实体的Map
     *
     * @param productIdList 产品id列表
     * @return Map 产品id-产品
     */
    @Override
    public Map<Long, Product> getListFromId(long instanceId, List<Long> productIdList) {
        List<Product> productList = productMapper.getFromIdList(instanceId, productIdList);
        return productList.stream().collect(Collectors.toMap(Product::getId, Function.identity()));
    }

    /**
     * 获取所有商品信息
     *
     * @param instanceId 实例id
     * @return List Map-id与商品名的列表
     */
    @Override
    public List<Map<String, Object>> getSelection(long instanceId) {
        //获取所有商品
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("instance_id", instanceId);
        List<Product> productList = productMapper.selectList(queryWrapper);
        //返还的数据结构
        ArrayList<Map<String, Object>> selectList = new ArrayList<>();
        for (Product item : productList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", item.getId().toString());
            map.put("text", item.getId().toString() + " " + item.getName() + " 可售" + item.getUnsell());
            selectList.add(map);
        }
        return selectList;
    }

    /**
     * 用于更新产品
     *
     * @param instanceId 实例id
     * @param product    产品实体
     * @throws CustomException 当实例不存在，产品信息不完整时抛出该异常
     */
    @Override
    public void updateProduct(long instanceId, Product product) throws CustomException {
        if (!userService.isInstance(instanceId)) {
            //非存在实例
            throw new CustomException(CustomExceptionType.INSTANCE_NOT_FOUND_ERROR, "找不到指定实例");
        }
        if (
                product.getId() == null ||
                        product.getName() == null || product.getName().isEmpty() ||
                        product.getPrice() == null ||
                        product.getCount() == null ||
                        product.getUnsell() == null
        ) {
            //数据不完整
            throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "数据不完整");
        }
        product.setInstanceId(instanceId);
        productMapper.updateById(product);
    }

    /**
     * 用于获取商品实体
     *
     * @param instanceId 实例id
     * @param productId  商品id
     * @return Product实体
     */
    @Override
    public Product get(long instanceId, long productId) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("instance_id", instanceId)
                .eq("id", productId);
        return productMapper.selectOne(queryWrapper);
    }

    /**
     * 用于上架商品
     *
     * @param rackId     货架id
     * @param productId  产品id
     * @param count      上架数量
     * @param instanceId 实例id
     */
    @Override
    @Transactional
    public void toRack(Long rackId, Long productId, Integer count, long instanceId) {
        //增加上架位置
        QueryWrapper<ProductRack> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("instance_id", instanceId)
                .eq("rack_id", rackId)
                .eq("product_id", productId);
        ProductRack productRack = productRackMapper.selectOne(queryWrapper);
        if (productRack == null) {
            productRack = new ProductRack(productId, rackId, count, instanceId);
            productRackMapper.insert(productRack);
        } else {
            productRack.setCount(productRack.getCount() + count);
            productRackMapper.updateById(productRack);
        }
        //修改商品数量
        Product product = get(instanceId, productId);
        product.setCount(product.getCount() + count);
        product.setUnsell(product.getUnsell() + count);
        productMapper.updateById(product);
    }

    /**
     * 用于查询是否存在商品
     *
     * @param productId 商品号
     * @return 是否存在该商品
     */
    public boolean isProduct(long productId) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", productId);
        return productMapper.selectCount(queryWrapper)>0;
    }
}
